NES CPU
The CPU inside of the NES is based on a 6502 core, the only difference being the lack of the 6502's BCD addition and subtraction mode. Aside from this, the CPU operates exactly like a normal 6502. = Registers = There are four 8-bit registers, and two 16-bit registers in the 2A03: A (8-bit) - Accumulator X (8-bit) - X Index Register Y (8-bit) - Y Index Register P (8-bit) - Processor Status Flags SP (16-bit) - Stack pointer PC (16-bit) - Program counter Flags The flags in the P''' register are ordered as such: N ($80) - Last operation resulted in a negative value V ($40) - Last operation resulted in an arithmetic overflow - - D ($08) - Decimal mode on/off (NOT USED IN THE 2A03/2A07) I ($04) - Interrupt inhibit flag Z ($02) - Last operation resulted in a zero C ($01) - Last operation resulted in a carry = Interrupts = Interrupts are controlled by two pins '''/NMI and /IRQ nominally. /NMI is the non-maskable interrupt, and is hardwired to the PPU for V-BLANK interrupts. /IRQ on the other hand is maskable, and therefor depends on the state of the I''' flag in register '''P. If I''' is set, then the interrupt isn't serviced (read: not acknowledged, not serviced). If the '''I flag becomes cleared, any previously unserviced IRQs will then be serviced. The Interrupt Service Routine (ISR) does the following when an IRQ or NMI is to be serviced: 1. Two wait states are executed, the purpose of this isn't known to me at the time of this writing. 2. Push PCH onto the stack 3. Push PCL onto the stack 4. Push P onto the stack 5. Read PCL from the proper vector (IRQ: $FFFE, NMI: $FFFA) 6. Read PCH from the proper vector (IRQ: $FFFF, NMI: $FFFB) 7. Set the I''' flag (NOTE: NMI doesn't do this step!) A small note about the above: Setting the '''I flag doesn't consume any cycles, and may very well be set during one of the two wait states that the CPU executes, and if any is most likely set in the first wait state, as the second may be used to ensure the flag is set (I''' setting or clearing seems to take a cycle to take effect). Similarities with /RST The above service routine is the same routine executed by the /RST line being pulled low on boots and resets. The only difference is that no actual data is pushed onto the stack, the '''SP is however decremented as if pushes took place. An easy way to emulate this behavior is: void RST(void) { sp.lo -= 0x3; p.i = true; pc.lo = read_byte(0xFFFC); pc.hi = read_byte(0xFFFD); } The more accurate way to emulate this behavior is: void RST(void) { read_byte(sp); sp.lo--; // read instead of write to pass time read_byte(sp); sp.lo--; read_byte(sp); sp.lo--; p.i = true; pc.lo = read_byte(0xFFFC); pc.hi = read_byte(0xFFFD); } One thing to note about the above 'more accurate' implementation is that it is unknown if the address bus has the SP on it during /RST. The above was assumed under the following line of reasoning: 1. All cycles in the 6502 are either reading from or writing to memory. 2. Nothing is written during /RST 3. Normally (During /IRQ and /NMI) data is being written to where the SP points Using those 3 points, I believe it is safe for now to assume that those reads occur. Of course, tests must be done and their findings must be accepted, even if it contradicts the above assumptions. Category:Nintendo Category:Nintendo Entertainment System